#include "stm32f10x.h"                   // Device header
#include "Delay.h"       
#include "OLED.h"       
#include "AD.h"         
#include "PID.h"         
#include "PWM.h"         
#include "Filtering.h"   
#include "Timer.h"
#include "Key.h"
#include "math.h"
#include "WatchDog.h"

/********************全局变量的定义********************/

int period_ms = 1;                    //定时器中断周期
float Actual_Voltage_now;              //实际电压(now)
float Actual_Voltage_past;             //实际电压(past)
float Actual_Voltage;                  //滤波后的电压
float Target_Voltage = 12.00;       	//目标电压
float Duty;                            //实时占空比
float CCR = 1800;                      //PWM的CCR的值
uint16_t Key_num;                      //按键检测变量

PID_Controller pid_control;  //结构化PID
/********************全局变量的定义********************/


double Incremental_PI1 (float Encoder,float Target)
{ 
	float Kp=36.5,Ki=4.2,Kd=0.01;	//Kp比例，Ki，
	static double Bias,Last_bias = 0,prev_bias = 0;
	static double Pwm;
	Bias=Target-Encoder;                //计算偏差
	Pwm=Kp*(Bias-Last_bias)+Ki*Bias+Kd*(Bias-2*Last_bias+prev_bias);   //增量式PID控制器
	prev_bias = Last_bias;
	Last_bias=Bias;	                   //保存上一次偏差 
	return Pwm;                         //增量输出
}

//定时器3中断,1ms一次,用于执行PID调控
void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
	{
		/* 用户代码开始 */
		
		Key_Tick();// 按键刷新

		//得到实际电压值,经行过滤操作,采用voltage_filter函数
		Actual_Voltage_past = Actual_Voltage_now;
		Actual_Voltage_now = ((float)AD_GetValue()) / 4095 * 3.3 * 15.915 + 0.313;//将AD值线性变换到0~24的范围，表示电压
		
		//对电压经行滤波
		Actual_Voltage = voltage_filter(Actual_Voltage_now, Actual_Voltage_past , 0.95f);
		//Actual_Voltage = Actual_Voltage_now;
        
		//执行PID调控
		CCR += Incremental_PI1(Actual_Voltage, Target_Voltage);
		
		//应用设置
		if (CCR > 3600) CCR = 3600;
		else if (CCR < 0) CCR = 0;
		PWM_SetCCR(CCR);
		
		/* 用户代码结束 */
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}


//主函数
int main(void)
{
	
	/*模块初始化*/
	
	OLED_Init();							//OLED初始化
	AD_Init();								//AD初始化
	//PID_Init(&pid_control, PID_KP,PID_KI,PID_KD,3600.0, 0.0, period_ms);	//PID初始化
	PWM_Init();             				//PWM初始化
	Timer3_Init(5);         		//定时器中断初始化
	Key_Init();                             //按键检测初始化
	IWDG_Init(250);                         //初始化看门狗
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "target:00.00V");
	OLED_ShowString(2, 1, "actual:00.00V");
	OLED_ShowString(3, 1, "CCR   :00000");
	OLED_ShowString(4, 1, "current:0.00A");
	
	// 默认占空比为50%
	PWM_SetCCR(CCR);
	
	while (1)
	{
		/*按键监测*/
		Key_num = Key_GetNum();
		if (Key_num == 1)
		{
			Target_Voltage += 1.0;
			
		}
		else if (Key_num == 2)
		{
			Target_Voltage -= 1.0;
			
		}
		

		/*电压显示*/
		// 显示目标电压
		OLED_ShowNum(1, 8, (int)Target_Voltage, 2);                                  //int部分
		OLED_ShowNum(1, 11, (int)((Target_Voltage - (int)Target_Voltage) * 100), 2); //float部分
		
		// 显示实际电压
		OLED_ShowNum(2, 8, (int)Actual_Voltage, 2);                                  //int部分
		OLED_ShowNum(2, 11, (int)((Actual_Voltage - (int)Actual_Voltage) * 100), 2); //folat部分
		
		// 显示实时CCR
		OLED_ShowNum(3, 8, (int)(CCR), 5);
	
		// 显示实际电压
		OLED_ShowNum(2, 8, (int)Actual_Voltage, 2);                                  //int部分
		OLED_ShowNum(2, 11, (int)((Actual_Voltage - (int)Actual_Voltage) * 100), 2); //folat部分

		// 喂狗
		IWDG_Feed();
	}
}
